package main

import (
	"fmt"
	"github.com/hajimehoshi/ebiten/v2"

	"time"
)

type Mode int

const (
	ModeTitle Mode = iota
	ModeGame
	ModeOver
)

type Game struct {
	mode   Mode
	Input  *Input
	Config *Config
	Ship   *Ship
	Bullet map[*Bullet]struct{}
	Alien  map[*Alien]struct{}
}

// 接口
type GameInterface interface {
	Draw(screen *ebiten.Image)
	Layout(outerWidth, outerHeight int) (screenWidth, screenHeight int)
}

// 接口的调用测试
//func test(g1 GameInterface,g2 *Game){
//	g1.Draw(nil)
//}

func NewGame() *Game {
	// 加载配置

	cfg := LoadConfig()

	// 宽高输入
	ebiten.SetWindowSize(cfg.ScreenWidth, cfg.ScreenHeight)
	ebiten.SetWindowTitle(cfg.Title)

	// 创建并返回Game对象
	g := &Game{
		mode: ModeTitle,
		Input: &Input{
			lastBulletTime: time.Now(),
		},
		Config: cfg,
		Ship:   NewShip(cfg.ScreenWidth, cfg.ScreenWidth),
		Bullet: make(map[*Bullet]struct{}),
		Alien:  make(map[*Alien]struct{}),
	}
	g.CreateAlien()
	return g
}
func (g *Game) Draw(screen *ebiten.Image) {

	screen.Fill(g.Config.BgColor)
	g.Ship.Draw(screen, g.Config)
	for bullet := range g.Bullet {
		bullet.Draw(screen)
	}
	for alien := range g.Alien {
		alien.Draw(screen)
	}
}
func (g *Game) Layout(outerWidth, outerHeight int) (screenWidth, screenHeight int) {
	return g.Config.ScreenWidth, g.Config.ScreenHeight
}

// 最后的测试
func (g *Game) Update() error {

	switch g.mode {
	case ModeTitle:
		fmt.Println(1)
		if ebiten.IsKeyPressed(ebiten.KeyEnter) {
			g.mode = ModeGame
		}
	case ModeGame:
		fmt.Println(2)
		for bullet := range g.Bullet {
			if bullet.outOfScreen() {
				delete(g.Bullet, bullet)
			}
			bullet.Y -= bullet.Speed
		}
		for alien := range g.Alien {
			alien.Y += alien.Speed
		}
		g.Input.Update(g.Ship, g.Config, g)
		for alien := range g.Alien {
			for bullet := range g.Bullet {
				if CheckCollision(bullet, alien) {
					delete(g.Bullet, bullet)
					delete(g.Alien, alien)
				}
			}
		}
		for alien := range g.Alien {
			if GameOverCheck(g.Ship, alien) {
				g.mode = ModeOver
			}
		}
	// 测试
	case ModeOver:
		fmt.Println(3)
		if ebiten.IsKeyPressed(ebiten.KeyEnter) {
			g.Alien = make(map[*Alien]struct{})
			g.mode = ModeTitle
			g.CreateAlien()
			g.Input = &Input{
				lastBulletTime: time.Now(),
			}

		}

	}
	return nil

}
func (g *Game) addBullet(bullet *Bullet) {
	// 表示，注重键值，而不注重value这个值，主要用于判断value
	g.Bullet[bullet] = struct{}{}
}
func (g *Game) addAlien(alien *Alien) {
	g.Alien[alien] = struct{}{}
}
